package com.xs.ahoi.hcxs.utils.tts;

import static com.xs.ahoi.hcxs.utils.Constants.BD_TTS_MODEL_FILENAME_PATH;
import static com.xs.ahoi.hcxs.utils.Constants.BD_TTS_TEXT_FILENAME_PATH;

import android.content.Context;
import android.media.AudioManager;
import android.os.Handler;
import android.os.Message;

import com.baidu.tts.client.SpeechError;
import com.baidu.tts.client.SpeechSynthesizer;
import com.baidu.tts.client.TtsMode;
import com.xs.ahoi.hcxs.dao.ConfigDao;
import com.xs.ahoi.hcxs.listener.BaiDuTtsListener;
import com.xs.ahoi.hcxs.utils.LogUtil;
import com.xs.ahoi.hcxs.utils.StringUtils;
import com.xs.ahoi.hcxs.utils.ToastUtil;
import com.xs.ahoi.hcxs.utils.tts.check.AutoCheck;
import com.xs.ahoi.hcxs.utils.tts.check.InitConfig;

import java.util.HashMap;
import java.util.Map;

/**
 * author: cdfuhuichao
 * date: 2019/4/25 14:51
 * path: com.xs.ahoi.hcxs.utils.tts.TtsBaiduUtil
 * description: 百度语音合成工具
 */
public class TtsBaiduUtil extends AbstractTTS {
    private static TtsBaiduUtil instance;
    private static final String APP_ID = "16109052";
    private static final String API_KEY = "x0iDwaUiMgYfPsqgf0AEuv4d";
    private static final String SECRET_KEY = "UN5BrR9MnV0KTb916IAiL1mGum68cuTl";
    private static final String SN = "99eeff5a-7f70ff2e-027a-00e6-22e32";

    // TtsMode.MIX; 离在线融合，在线优先； TtsMode.ONLINE 纯在线； 没有纯离线
    private TtsMode ttsMode = TtsMode.MIX;

    private SpeechSynthesizer tts;
    private boolean isComplete = true, restart = true;

    BaiDuTtsListener listener = new BaiDuTtsListener() {
        @Override
        public void onSpeechFinish(String utteranceId) {
            if (ttsListener != null && ttsListener.isPlaying()) {
                restart = isComplete = true;
                next();
            } else if (APP_PLAYING) {
                appTTSListener.finish();
            }
        }

        @Override
        public void onError(String utteranceId, SpeechError speechError) {
            super.onError(utteranceId, speechError);
            onSpeechFinish(utteranceId);
        }
    };

    private TtsBaiduUtil(Context context) {
        init(context);
    }

    public static TtsBaiduUtil getInstance() {
        return instance;
    }

    public static TtsBaiduUtil createInstance(Context context) {
        if (instance == null) {
            instance = new TtsBaiduUtil(context);
        }
        return instance;
    }

    // 初始化
    public void init(Context context) {

        // 检查离线资源bat file是否可读
        OfflineResource.check();

        // 1. 获取实例
        tts = SpeechSynthesizer.getInstance();
        tts.setContext(context);

        // 2. 设置listener
        tts.setSpeechSynthesizerListener(listener);

        // 3. 设置appId，appKey.secretKey
        tts.setAppId(APP_ID);
        tts.setApiKey(API_KEY, SECRET_KEY);

        // 4.设置参数
        setParams();

        // 5.检查离线授权文件是否下载成功，离线授权文件联网时SDK自动下载管理，有效期3年，3年后的最后一个月自动更新。
        if (!checkAuth(context)) {
            return;
        }

        // 6. 初始化
        int result = tts.initTts(ttsMode);
        if (result != 0) {
            print("初始化tts失败，error code :" + result, true);
            print("错误码文档:https://ai.baidu.com/ai-doc/SPEECH/Ck4nwu2vx");
        }
    }

    public boolean start() {
        if (tts == null) {
            print("百度tts初始化失败", true);
            return false;
        }

        if (restart || lineIndexs.isEmpty()) {
            String speakText = getSpeakText();
            if (StringUtils.isEmpty(StringUtils.replaceWrap(speakText))) {
                next();
                return true;
            }
            tts.speak(speakText);
            ttsListener.refreshPage();
            restart = false;
        } else {
            resume();
        }
        return true;

    }

    private void resume() {
        if (restart || isComplete) {
            ttsListener.nextPage();
            start();
        } else {
            if (tts != null) {
                tts.resume();
            }
        }
    }

    public boolean speakText(String text) {
        return 0 == tts.speak(text);
    }

    public void onlyStop() {
        tts.stop();
    }

    public void stop() {
        lineIndexs.clear();
        tts.stop();
    }

    public void pause() {
        isComplete = false;
        tts.pause();
    }

    public void reset() {
        stop();
        restart = true;
        isComplete = false;
        lineIndexPrev = lineIndexCurrent = 0;
    }

    // 检查离线授权文件是否下载成功，离线授权文件联网时SDK自动下载管理，有效期3年，3年后的最后一个月自动更新。
    private boolean checkAuth(Context context) {

        // x. 额外 ： 自动so文件是否复制正确及上面设置的参数
        Map<String, String> params = new HashMap<>();
        // 上线时请删除AutoCheck的调用
        // 文本模型文件路径 (离线引擎使用)， 注意TEXT_FILENAME必须存在并且可读
        params.put(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, BD_TTS_TEXT_FILENAME_PATH);
        // 声学模型文件路径 (离线引擎使用)， 注意TEXT_FILENAME必须存在并且可读
        params.put(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE, BD_TTS_MODEL_FILENAME_PATH);

        // 检测参数，通过一次后可以去除，出问题再打开debug
        InitConfig initConfig = new InitConfig(APP_ID, API_KEY, SECRET_KEY, ttsMode, params, listener);
        AutoCheck.getInstance(context.getApplicationContext()).check(initConfig, new Handler() {
            @Override
            /**
             * 开新线程检查，成功后回调
             */
            public void handleMessage(Message msg) {
                if (msg.what == 100) {
                    AutoCheck autoCheck = (AutoCheck) msg.obj;
                    synchronized (autoCheck) {
                        String message = autoCheck.obtainDebugMessage();
                        print(message); // 可以用下面一行替代，在logcat中查看代码
                    }
                }
            }
        });
        return true;
    }

    private void print(String msg) {
        print(msg, false);
    }

    private void print(String msg, boolean toast) {
        LogUtil.e(msg);
        if (toast) {
            ToastUtil.show(msg);
        }
    }

    // 设置参数
    private void setParams() {
        // 文本模型文件路径 (离线引擎使用)， 注意TEXT_FILENAME必须存在并且可读
        tts.setParam(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, BD_TTS_TEXT_FILENAME_PATH);
        // 声学模型文件路径 (离线引擎使用)， 注意TEXT_FILENAME必须存在并且可读
        tts.setParam(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE, BD_TTS_MODEL_FILENAME_PATH);

        // 以下setParam 参数选填。不填写则默认值生效
        // 设置在线发声音人： 0 普通女声（默认） 1 普通男声 2 特别男声 3 情感男声<度逍遥> 4 情感儿童声<度丫丫>
        tts.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0");
        // 设置合成的音量
        tts.setParam(SpeechSynthesizer.PARAM_VOLUME, "15");
        // 设置语速和语调
        changeTtsParam();
        // MIX_MODE_HIGH_SPEED_SYNTHESIZE_WIFI wifi状态下使用在线，非wifi离线。在线状态下，请求超时1.2s自动转离线
        tts.setParam(SpeechSynthesizer.PARAM_MIX_MODE, SpeechSynthesizer.MIX_MODE_HIGH_SPEED_SYNTHESIZE_WIFI);
        // MODE_IN_CALL、AudioManager.STREAM_MUSIC 指的是用与音乐播放的音频流
        tts.setAudioStreamType(AudioManager.STREAM_MUSIC);

        // 纯离线sdk这个参数必填；离在线sdk没有此参数
//        tts.setParam(SpeechSynthesizer.PARAM_AUTH_SN, SN);
    }

    public void changeTtsParam() {
        // tts语速（百度）
        int speed = ConfigDao.getInstance().getTtsSpeed();
        // tts语调（百度）
        int tones = ConfigDao.getInstance().getTtsTones();
        tts.setParam(SpeechSynthesizer.PARAM_SPEED, String.valueOf(speed));
        tts.setParam(SpeechSynthesizer.PARAM_PITCH, String.valueOf(tones));
    }

}
